home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / var / lib / python-support / python2.6 / glchess / scene / opengl / opengl.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  24.7 KB  |  819 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import math
  5. import os.path as os
  6. from gettext import gettext as _
  7. import cairo
  8. from OpenGL.GL import *
  9. from OpenGL.GLU import *
  10. from glchess.defaults import *
  11. import glchess.scene as glchess
  12. import texture
  13. import new_models
  14. builtin_models = new_models
  15. PIECE_MOVE_SPEED = 50
  16. BOARD_ROTATION_TIME = 0.8
  17. SQUARE_WIDTH = 10
  18. BOARD_DEPTH = 3
  19. BOARD_BORDER = 5
  20. BOARD_CHAMFER = 2
  21. BOARD_INNER_WIDTH = SQUARE_WIDTH * 8
  22. BOARD_OUTER_WIDTH = BOARD_INNER_WIDTH + BOARD_BORDER * 2
  23. OFFSET = BOARD_OUTER_WIDTH * 0.5
  24. LIGHT_AMBIENT_COLOUR = (0.4, 0.4, 0.4, 1)
  25. LIGHT_DIFFUSE_COLOUR = (0.7, 0.7, 0.7, 1)
  26. LIGHT_SPECULAR_COLOUR = (1, 1, 1, 1)
  27. BOARD_AMBIENT = (0.2, 0.2, 0.2, 1)
  28. BOARD_DIFFUSE = (0.8, 0.8, 0.8, 1)
  29. BOARD_SPECULAR = (1, 1, 1, 1)
  30. BOARD_SHININESS = 128
  31. BACKGROUND_COLOUR = (0.53, 0.63, 0.75, 0)
  32. BORDER_COLOUR = (0.72, 0.33, 0)
  33. BLACK_SQUARE_COLOURS = {
  34.     None: (0.8, 0.8, 0.8),
  35.     glchess.scene.HIGHLIGHT_SELECTED: (0.3, 1, 0.3),
  36.     glchess.scene.HIGHLIGHT_CAN_MOVE: (0.3, 0.3, 1),
  37.     glchess.scene.HIGHLIGHT_THREATENED: (1, 0.8, 0.8),
  38.     glchess.scene.HIGHLIGHT_CAN_TAKE: (1, 0.3, 0.3) }
  39. WHITE_SQUARE_COLOURS = {
  40.     None: (1, 1, 1),
  41.     glchess.scene.HIGHLIGHT_SELECTED: (0.2, 1, 0),
  42.     glchess.scene.HIGHLIGHT_CAN_MOVE: (0.2, 0.2, 0.8),
  43.     glchess.scene.HIGHLIGHT_THREATENED: (1, 0.8, 0.8),
  44.     glchess.scene.HIGHLIGHT_CAN_TAKE: (1, 0.2, 0.2) }
  45. import math
  46.  
  47. def accFrustum(left, right, bottom, top, near, far, pixdx, pixdy, eyedx, eyedy, focus):
  48.     viewport = glGetIntegerv(GL_VIEWPORT)
  49.     xwsize = right - left
  50.     ywsize = top - bottom
  51.     dx = -(pixdx * xwsize / viewport[2] + eyedx * near / focus)
  52.     dy = -(pixdy * ywsize / viewport[3] + eyedy * near / focus)
  53.     glFrustum(left + dx, right + dx, bottom + dy, top + dy, near, far)
  54.     glTranslatef(-eyedx, -eyedy, 0)
  55.  
  56.  
  57. def accPerspective(fovy, aspect, near, far, pixdx, pixdy, eyedx, eyedy, focus):
  58.     fov2 = fovy * math.pi / 180 / 2
  59.     top = near / math.cos(fov2) / math.sin(fov2)
  60.     bottom = -top
  61.     right = top * aspect
  62.     left = -right
  63.     accFrustum(left, right, bottom, top, near, far, pixdx, pixdy, eyedx, eyedy, focus)
  64.  
  65.  
  66. class ChessPiece(glchess.scene.ChessPiece):
  67.     '''
  68.     '''
  69.     scene = None
  70.     chessSet = None
  71.     name = None
  72.     location = ''
  73.     pos = None
  74.     targetPos = None
  75.     moving = False
  76.     delete = False
  77.     
  78.     def __init__(self, scene, chessSet, name, location, feedback):
  79.         '''
  80.         '''
  81.         self.scene = scene
  82.         self.feedback = feedback
  83.         self.chessSet = chessSet
  84.         self.name = name
  85.         self.location = location
  86.         self.pos = self.scene._coordToLocation(location)
  87.  
  88.     
  89.     def move(self, coord, delete, animate = True):
  90.         '''Extends glchess.scene.ChessPiece'''
  91.         if not coord:
  92.             self.scene.pieces.remove(self)
  93.             self.feedback.onDeleted()
  94.             return None
  95.         self.delete = delete
  96.         self.location = coord
  97.         self.targetPos = self.scene._coordToLocation(coord)
  98.         if self.pos == self.targetPos:
  99.             self.targetPos = None
  100.             if delete:
  101.                 self.scene.pieces.remove(self)
  102.                 self.feedback.onDeleted()
  103.                 self.scene.feedback.onRedraw()
  104.             
  105.             return None
  106.  
  107.     
  108.     def draw(self, state = 'default'):
  109.         '''
  110.         '''
  111.         self.chessSet.drawPiece(self.name, state, self.scene)
  112.  
  113.     
  114.     def animate(self, timeStep):
  115.         '''
  116.         
  117.         Return True if the piece has moved otherwise False.
  118.         '''
  119.         if self.targetPos is None:
  120.             return False
  121.         if self.pos == self.targetPos:
  122.             self.targetPos = None
  123.             if self.delete:
  124.                 self.scene.pieces.remove(self)
  125.                 self.feedback.onDeleted()
  126.             
  127.             return False
  128.         dx = self.targetPos[0] - self.pos[0]
  129.         dy = self.targetPos[1] - self.pos[1]
  130.         dz = self.targetPos[2] - self.pos[2]
  131.         xStep = timeStep * PIECE_MOVE_SPEED
  132.         yStep = timeStep * PIECE_MOVE_SPEED
  133.         if yStep > abs(dy):
  134.             yStep = dy
  135.         else:
  136.             yStep *= cmp(dy, 0)
  137.         zStep = timeStep * PIECE_MOVE_SPEED
  138.         if zStep > abs(dz):
  139.             zStep = dz
  140.         else:
  141.             zStep *= cmp(dz, 0)
  142.         self.pos = (self.pos[0] + xStep, self.pos[1] + yStep, self.pos[2] + zStep)
  143.         return True
  144.  
  145.  
  146.  
  147. class Scene(glchess.scene.Scene):
  148.     '''
  149.     '''
  150.     viewportWidth = 0
  151.     viewportHeight = 0
  152.     viewportAspect = 1
  153.     animating = False
  154.     throbberEnabled = False
  155.     throbberAngle = 0
  156.     lightPos = None
  157.     boardAngle = 0
  158.     oldBoardAngle = 0
  159.     targetBoardAngle = 0
  160.     boardList = None
  161.     regenerateBoard = False
  162.     whiteTexture = None
  163.     blackTexture = None
  164.     pieces = None
  165.     chessSets = None
  166.     piecesMoving = False
  167.     highlights = None
  168.     _animationQueue = []
  169.     jitters = ((0, 0),)
  170.     showNumbering = False
  171.     numberingTexture = None
  172.     
  173.     def __init__(self, feedback):
  174.         '''Constructor for an OpenGL scene'''
  175.         self.feedback = feedback
  176.         self.lightPos = [
  177.             100,
  178.             100,
  179.             100,
  180.             1]
  181.         self.pieces = []
  182.         self.highlights = { }
  183.         self._animationQueue = []
  184.         self.chessSets = {
  185.             'white': builtin_models.WhiteBuiltinSet(),
  186.             'black': builtin_models.BlackBuiltinSet() }
  187.         self.whiteTexture = texture.Texture(os.path.join(TEXTURE_DIR, 'board.png'), ambient = BOARD_AMBIENT, diffuse = BOARD_DIFFUSE, specular = BOARD_SPECULAR, shininess = BOARD_SHININESS)
  188.         self.blackTexture = texture.Texture(os.path.join(TEXTURE_DIR, 'board.png'), ambient = BOARD_AMBIENT, diffuse = BOARD_DIFFUSE, specular = BOARD_SPECULAR, shininess = BOARD_SHININESS)
  189.  
  190.     
  191.     def onRedraw(self):
  192.         '''This method is called when the scene needs redrawing'''
  193.         pass
  194.  
  195.     
  196.     def addChessPiece(self, chessSet, name, coord, feedback):
  197.         """Add a chess piece model into the scene.
  198.         
  199.         'chessSet' is the name of the chess set (string).
  200.         'name' is the name of the piece (string).
  201.         'coord' is the the chess board location of the piece in LAN format (string).
  202.         'feedback' is the feedback object (extends scene.ChessPieceFeedback).
  203.  
  204.         Returns a reference to this chess piece or raises an exception.
  205.         """
  206.         chessSet = self.chessSets[chessSet]
  207.         piece = ChessPiece(self, chessSet, name, coord, feedback)
  208.         self.pieces.append(piece)
  209.         self.feedback.onRedraw()
  210.         return piece
  211.  
  212.     
  213.     def setBoardHighlight(self, coords):
  214.         """Highlight a square on the board.
  215.         
  216.         'coords' is a dictionary of highlight types keyed by square co-ordinates.
  217.                  The co-ordinates are a tuple in the form (file,rank).
  218.                  If None the highlight will be cleared.
  219.         """
  220.         if coords is None:
  221.             self.highlights = { }
  222.         else:
  223.             self.highlights = coords.copy()
  224.         self.regenerateBoard = True
  225.         self.feedback.onRedraw()
  226.  
  227.     
  228.     def showBoardNumbering(self, showNumbering):
  229.         '''Extends glchess.scene.Scene'''
  230.         self.showNumbering = showNumbering
  231.         self.feedback.onRedraw()
  232.  
  233.     
  234.     def showSmooth(self, doSmooth):
  235.         if doSmooth:
  236.             self.jitters = ((0.00339226, 0.331797), (0.280602, -0.249562), (-0.273817, -0.0868446))
  237.         else:
  238.             self.jitters = ((0, 0),)
  239.         self.feedback.onRedraw()
  240.  
  241.     
  242.     def reshape(self, width, height):
  243.         """Resize the viewport into the scene.
  244.         
  245.         'width' is the width of the viewport in pixels.
  246.         'height' is the width of the viewport in pixels.
  247.         """
  248.         self.viewportWidth = int(width)
  249.         self.viewportHeight = int(height)
  250.         self.viewportAspect = float(self.viewportWidth) / float(self.viewportHeight)
  251.         glViewport(0, 0, self.viewportWidth, self.viewportHeight)
  252.         self.feedback.onRedraw()
  253.  
  254.     
  255.     def setBoardRotation(self, angle, animate = True):
  256.         """Set the rotation on the board.
  257.         
  258.         'angle' is the angle the board should be drawn at in degress (float, [0.0, 360.0]).
  259.         """
  260.         self.targetBoardAngle = angle
  261.         if not animate:
  262.             self.oldBoardAngle = self.boardAngle = angle
  263.             self.feedback.onRedraw()
  264.             return None
  265.         if self.animating is False:
  266.             self.animating = True
  267.             self.feedback.startAnimation()
  268.         
  269.  
  270.     
  271.     def animate(self, timeStep):
  272.         '''Extends glchess.scene.Scene'''
  273.         redraw1 = self.animateThrobber(timeStep)
  274.         self.piecesMoving = self.animatePieces(timeStep)
  275.         redraw2 = self.animateRotation(timeStep)
  276.         if redraw1 and redraw2 or self.piecesMoving:
  277.             self.animating = True
  278.             self.feedback.onRedraw()
  279.         else:
  280.             self.animating = False
  281.         return self.animating
  282.  
  283.     
  284.     def render(self):
  285.         '''Render the scene.
  286.         
  287.         This requires an OpenGL context.
  288.         '''
  289.         glClearColor(*BACKGROUND_COLOUR)
  290.         if len(self.jitters) > 1:
  291.             glClear(GL_ACCUM_BUFFER_BIT)
  292.         
  293.         glLightfv(GL_LIGHT0, GL_AMBIENT, LIGHT_AMBIENT_COLOUR)
  294.         glLightfv(GL_LIGHT0, GL_DIFFUSE, LIGHT_DIFFUSE_COLOUR)
  295.         glLightfv(GL_LIGHT0, GL_SPECULAR, LIGHT_SPECULAR_COLOUR)
  296.         for jitter in self.jitters:
  297.             glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
  298.             glMatrixMode(GL_PROJECTION)
  299.             glLoadIdentity()
  300.             if len(self.jitters) > 1:
  301.                 accPerspective(60, self.viewportAspect, 0.1, 1000, jitter[0], jitter[1], 0, 0, 1)
  302.             else:
  303.                 gluPerspective(60, self.viewportAspect, 0.1, 1000)
  304.             glMatrixMode(GL_MODELVIEW)
  305.             glLoadIdentity()
  306.             self.transformCamera()
  307.             glLightfv(GL_LIGHT0, GL_POSITION, self.lightPos)
  308.             glEnable(GL_LIGHTING)
  309.             glEnable(GL_LIGHT0)
  310.             self.transformBoard()
  311.             glEnable(GL_DEPTH_TEST)
  312.             glEnable(GL_CULL_FACE)
  313.             glEnable(GL_TEXTURE_2D)
  314.             glEnable(GL_COLOR_MATERIAL)
  315.             self.drawBoard()
  316.             glDisable(GL_COLOR_MATERIAL)
  317.             glDisable(GL_TEXTURE_2D)
  318.             if self.showNumbering:
  319.                 self.drawNumbering()
  320.             
  321.             glClear(GL_DEPTH_BUFFER_BIT)
  322.             if self.throbberEnabled:
  323.                 self.drawThrobber()
  324.             else:
  325.                 self.drawPieces()
  326.             if len(self.jitters) > 1:
  327.                 glAccum(GL_ACCUM, 1 / len(self.jitters))
  328.                 continue
  329.         
  330.         if len(self.jitters) > 1:
  331.             glAccum(GL_RETURN, 1)
  332.         
  333.  
  334.     
  335.     def getSquare(self, x, y):
  336.         """Find the chess square at a given 2D location.
  337.         
  338.         'x' is the number of pixels from the left of the scene to select.
  339.         'y' is the number of pixels from the bottom of the scene to select.
  340.         
  341.         This requires an OpenGL context.
  342.         
  343.         Return the co-ordinate in LAN format (string) or None if no square at this point.
  344.         """
  345.         viewport = glGetIntegerv(GL_VIEWPORT)
  346.         glSelectBuffer(20)
  347.         glRenderMode(GL_SELECT)
  348.         glInitNames()
  349.         glMatrixMode(GL_PROJECTION)
  350.         glLoadIdentity()
  351.         gluPickMatrix(x, float(viewport[3]) - y, 1, 1, viewport)
  352.         gluPerspective(60, float(viewport[2]) / float(viewport[3]), 0, 1)
  353.         glMatrixMode(GL_MODELVIEW)
  354.         glLoadIdentity()
  355.         self.transformCamera()
  356.         self.transformBoard()
  357.         self.drawSquares()
  358.         glFlush()
  359.         
  360.         try:
  361.             records = glRenderMode(GL_RENDER)
  362.         except GLerror:
  363.             coord = None
  364.  
  365.         if len(records) > 0:
  366.             (_, _, coord) = records[0]
  367.         else:
  368.             coord = None
  369.         glMatrixMode(GL_PROJECTION)
  370.         glLoadIdentity()
  371.         gluPerspective(60, float(viewport[2]) / float(viewport[3]), 0.1, 1000)
  372.         if coord is None:
  373.             return None
  374.         rank = chr(ord('a') + coord[0])
  375.         file = chr(ord('1') + coord[1])
  376.         return rank + file
  377.  
  378.     
  379.     def _coordToLocation(self, coord):
  380.         '''
  381.         '''
  382.         rank = ord(coord[0]) - ord('a')
  383.         file = ord(coord[1]) - ord('1')
  384.         x = BOARD_BORDER + float(rank) * SQUARE_WIDTH + 0.5 * SQUARE_WIDTH
  385.         z = -(BOARD_BORDER + float(file) * SQUARE_WIDTH + 0.5 * SQUARE_WIDTH)
  386.         return (x, 0, z)
  387.  
  388.     
  389.     def animateThrobber(self, timeStep):
  390.         '''
  391.         '''
  392.         if self.throbberEnabled is False:
  393.             return False
  394.         self.throbberAngle += timeStep * math.pi * 2 / 2
  395.         while self.throbberAngle > math.pi * 2:
  396.             self.throbberAngle -= 2 * math.pi
  397.             continue
  398.             self
  399.         return True
  400.  
  401.     
  402.     def animateRotation(self, timeStep):
  403.         '''
  404.         '''
  405.         if self.boardAngle == self.targetBoardAngle:
  406.             return False
  407.         if self.piecesMoving:
  408.             return False
  409.         length = abs(self.targetBoardAngle - self.oldBoardAngle)
  410.         self.boardAngle += timeStep * length / BOARD_ROTATION_TIME
  411.         while self.boardAngle > 360:
  412.             self.boardAngle -= 360
  413.             continue
  414.             self
  415.         travelled = self.targetBoardAngle - self.boardAngle
  416.         while travelled < 0:
  417.             travelled += 360
  418.             continue
  419.             self
  420.         return True
  421.  
  422.     
  423.     def animatePieces(self, timeStep):
  424.         '''
  425.         '''
  426.         if len(self._animationQueue) == 0:
  427.             return False
  428.         redraw = False
  429.         animationQueue = []
  430.         for piece in self._animationQueue:
  431.             if piece.animate(timeStep):
  432.                 piece.moving = True
  433.                 redraw = True
  434.                 if not animationQueue.count(piece) == 0:
  435.                     raise AssertionError
  436.                 animationQueue.append(piece)
  437.                 continue
  438.             animationQueue.count(piece) == 0
  439.             if piece.moving:
  440.                 redraw = True
  441.                 self.redrawStatic = True
  442.             
  443.             piece.moving = False
  444.             piece.feedback.onMoved()
  445.         
  446.         self._animationQueue = animationQueue
  447.         if redraw:
  448.             self.feedback.onRedraw()
  449.         
  450.         return len(self._animationQueue) > 0
  451.  
  452.     
  453.     def drawThrobber(self):
  454.         '''
  455.         '''
  456.         glDisable(GL_LIGHTING)
  457.         glDisable(GL_DEPTH_TEST)
  458.         glMatrixMode(GL_PROJECTION)
  459.         glLoadIdentity()
  460.         if self.viewportWidth > self.viewportHeight:
  461.             h = 1
  462.             w = 1 * self.viewportWidth / self.viewportHeight
  463.         else:
  464.             h = 1 * self.viewportHeight / self.viewportWidth
  465.             w = 1
  466.         gluOrtho2D(0, w, 0, h)
  467.         glMatrixMode(GL_MODELVIEW)
  468.         glLoadIdentity()
  469.         glEnable(GL_BLEND)
  470.         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
  471.         glColor4f(0, 0, 0, 0.75)
  472.         glBegin(GL_QUADS)
  473.         glVertex2f(-1, -1)
  474.         glVertex2f(w + 1, -1)
  475.         glVertex2f(w + 1, h + 1)
  476.         glVertex2f(-1, h + 1)
  477.         glEnd()
  478.         NSECTIONS = 9
  479.         RADIUS_OUT0 = 0.4
  480.         RADIUS_OUT1 = 0.43
  481.         RADIUS_OUT2 = 0.4
  482.         RADIUS_IN0 = 0.25
  483.         RADIUS_IN1 = 0.24
  484.         RADIUS_IN2 = 0.25
  485.         STEP_ANGLE = 2 * math.pi / float(NSECTIONS)
  486.         HALF_WIDTH = 0.8 * 0.5 * STEP_ANGLE
  487.         glTranslatef(0.5 * w, 0.5 * h, 0)
  488.         glBegin(GL_QUADS)
  489.         for i in xrange(NSECTIONS):
  490.             theta = 2 * math.pi * float(i) / float(NSECTIONS)
  491.             leadTheta = theta + HALF_WIDTH
  492.             lagTheta = theta - HALF_WIDTH
  493.             x0 = math.sin(leadTheta)
  494.             y0 = math.cos(leadTheta)
  495.             x1 = math.sin(theta)
  496.             y1 = math.cos(theta)
  497.             x2 = math.sin(lagTheta)
  498.             y2 = math.cos(lagTheta)
  499.             angleDifference = self.throbberAngle - theta
  500.             if angleDifference > math.pi:
  501.                 angleDifference -= 2 * math.pi
  502.             elif angleDifference < -(math.pi):
  503.                 angleDifference += 2 * math.pi
  504.             
  505.             stepDifference = angleDifference / STEP_ANGLE
  506.             if stepDifference > -0.5 and stepDifference < 0.5:
  507.                 x = 2 * abs(stepDifference)
  508.                 glColor4f(1, x, x, 0.6)
  509.             else:
  510.                 glColor4f(1, 1, 1, 0.6)
  511.             glVertex2f(RADIUS_IN0 * x0, RADIUS_IN0 * y0)
  512.             glVertex2f(RADIUS_OUT0 * x0, RADIUS_OUT0 * y0)
  513.             glVertex2f(RADIUS_OUT1 * x1, RADIUS_OUT1 * y1)
  514.             glVertex2f(RADIUS_IN1 * x1, RADIUS_IN1 * y1)
  515.             glVertex2f(RADIUS_IN1 * x1, RADIUS_IN1 * y1)
  516.             glVertex2f(RADIUS_OUT1 * x1, RADIUS_OUT1 * y1)
  517.             glVertex2f(RADIUS_OUT2 * x2, RADIUS_OUT2 * y2)
  518.             glVertex2f(RADIUS_IN2 * x2, RADIUS_IN2 * y2)
  519.         
  520.         glEnd()
  521.         glDisable(GL_BLEND)
  522.  
  523.     
  524.     def transformCamera(self):
  525.         '''Perform the camera matrix transformation'''
  526.         gluLookAt(0, 90, 45, 0, 0, 5, 0, 1, 0)
  527.  
  528.     
  529.     def _makeNumberingTexture(self):
  530.         WIDTH = 64
  531.         HEIGHT = 64
  532.         TEXTURE_WIDTH = WIDTH * 16
  533.         TEXTURE_HEIGHT = HEIGHT
  534.         surface = cairo.ImageSurface(cairo.FORMAT_A8, TEXTURE_WIDTH, TEXTURE_HEIGHT)
  535.         context = cairo.Context(surface)
  536.         context.set_source_rgba(1, 1, 1, 1)
  537.         context.select_font_face('sans-serif', cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
  538.         context.set_font_size(WIDTH)
  539.         (ascent, descent, x, x, x) = context.font_extents()
  540.         scale = WIDTH / (ascent + descent)
  541.         
  542.         def drawCenteredText(x, y, scale, text):
  543.             (w2, h2, w, h, _, _) = context.text_extents(text)
  544.             matrix = context.get_matrix()
  545.             context.translate(x, y)
  546.             context.move_to(-w * scale / 2, h * scale / 2)
  547.             context.scale(scale, scale)
  548.             context.show_text(text)
  549.             context.set_matrix(matrix)
  550.  
  551.         yoffset = HEIGHT * 0.5
  552.         xoffset = WIDTH * 0.5
  553.         for i in xrange(8):
  554.             f = 'abcdefgh'[i]
  555.             r = '12345678'[i]
  556.             drawCenteredText(xoffset, yoffset, scale, glchess.chess.translate_file(f))
  557.             drawCenteredText(xoffset + WIDTH * 8, yoffset, scale, glchess.chess.translate_rank(r))
  558.             xoffset += WIDTH
  559.         
  560.         t = glGenTextures(1)
  561.         glBindTexture(GL_TEXTURE_2D, t)
  562.         glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
  563.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
  564.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
  565.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
  566.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
  567.         data = surface.get_data()
  568.         
  569.         try:
  570.             gluBuild2DMipmaps(GL_TEXTURE_2D, GL_ALPHA, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_ALPHA, GL_UNSIGNED_BYTE, str(data))
  571.         except GLUerror:
  572.             (None,)
  573.             e = (None,)
  574.             glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_ALPHA, GL_UNSIGNED_BYTE, str(data))
  575.         except:
  576.             (None,)
  577.  
  578.         return t
  579.  
  580.     
  581.     def drawNumbering(self):
  582.         if self.numberingTexture is None:
  583.             self.numberingTexture = self._makeNumberingTexture()
  584.         
  585.         TEXT_WIDTH = BOARD_BORDER * 0.8
  586.         TEXT_OFFSET = (BOARD_BORDER + BOARD_CHAMFER) * 0.5
  587.         offset = BOARD_BORDER + SQUARE_WIDTH * 0.5
  588.         whiteZOffset = -TEXT_OFFSET
  589.         blackZOffset = -BOARD_OUTER_WIDTH + TEXT_OFFSET
  590.         leftOffset = TEXT_OFFSET
  591.         rightOffset = BOARD_OUTER_WIDTH - TEXT_OFFSET
  592.         
  593.         def drawLabel(x, z, cell):
  594.             w = 1 / 16
  595.             l = cell / 16
  596.             glPushMatrix()
  597.             glTranslatef(x, 0, z)
  598.             glRotatef(-(self.boardAngle), 0, 1, 0)
  599.             glBegin(GL_QUADS)
  600.             glTexCoord2f(l, 0)
  601.             glVertex3f(-TEXT_WIDTH / 2, 0, -TEXT_WIDTH / 2)
  602.             glTexCoord2f(l, 1)
  603.             glVertex3f(-TEXT_WIDTH / 2, 0, TEXT_WIDTH / 2)
  604.             glTexCoord2f(l + w, 1)
  605.             glVertex3f(TEXT_WIDTH / 2, 0, TEXT_WIDTH / 2)
  606.             glTexCoord2f(l + w, 0)
  607.             glVertex3f(TEXT_WIDTH / 2, 0, -TEXT_WIDTH / 2)
  608.             glEnd()
  609.             glPopMatrix()
  610.  
  611.         glNormal3f(0, 1, 0)
  612.         glDisable(GL_DEPTH_TEST)
  613.         glEnable(GL_TEXTURE_2D)
  614.         glEnable(GL_BLEND)
  615.         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
  616.         glBindTexture(GL_TEXTURE_2D, self.numberingTexture)
  617.         for i in xrange(8):
  618.             drawLabel(leftOffset, -offset, i + 8)
  619.             drawLabel(rightOffset, -offset, i + 8)
  620.             drawLabel(offset, whiteZOffset, i)
  621.             drawLabel(offset, blackZOffset, i)
  622.             offset += SQUARE_WIDTH
  623.         
  624.         glEnable(GL_DEPTH_TEST)
  625.         glDisable(GL_BLEND)
  626.         glDisable(GL_TEXTURE_2D)
  627.  
  628.     
  629.     def drawBoard(self):
  630.         '''Draw a chessboard'''
  631.         if self.regenerateBoard is False and self.boardList is not None:
  632.             glCallList(self.boardList)
  633.             return None
  634.         if self.boardList is None:
  635.             list = glGenLists(1)
  636.             if list != 0:
  637.                 self.boardList = list
  638.             
  639.         
  640.         if self.boardList is not None:
  641.             glNewList(self.boardList, GL_COMPILE)
  642.         
  643.         glColor3f(*BORDER_COLOUR)
  644.         a = 0
  645.         b = BOARD_CHAMFER
  646.         c = BOARD_BORDER
  647.         d = c + SQUARE_WIDTH * 8
  648.         e = d + BOARD_BORDER - BOARD_CHAMFER
  649.         f = d + BOARD_BORDER
  650.         l = 0
  651.         k = -BOARD_CHAMFER
  652.         j = -BOARD_BORDER
  653.         i = j - SQUARE_WIDTH * 8
  654.         h = (i - BOARD_BORDER) + BOARD_CHAMFER
  655.         g = i - BOARD_BORDER
  656.         verticies = [
  657.             (c, 0, i),
  658.             (d, 0, i),
  659.             (d, 0, j),
  660.             (c, 0, j),
  661.             (b, 0, h),
  662.             (e, 0, h),
  663.             (e, 0, k),
  664.             (b, 0, k),
  665.             (a, -BOARD_CHAMFER, g),
  666.             (f, -BOARD_CHAMFER, g),
  667.             (f, -BOARD_CHAMFER, l),
  668.             (a, -BOARD_CHAMFER, l),
  669.             (a, -BOARD_DEPTH, g),
  670.             (f, -BOARD_DEPTH, g),
  671.             (f, -BOARD_DEPTH, l),
  672.             (a, -BOARD_DEPTH, l)]
  673.         normals = [
  674.             (0, 1, 0),
  675.             (0, 0, -1),
  676.             (1, 0, 0),
  677.             (0, 0, 1),
  678.             (-1, 0, 0),
  679.             (0, 0.707, -0.707),
  680.             (0.707, 0.707, 0),
  681.             (0, 0.707, 0.707),
  682.             (-0.707, 0.707, 0)]
  683.         quads = [
  684.             (0, 1, 5, 4, 0),
  685.             (1, 2, 6, 5, 0),
  686.             (2, 3, 7, 6, 0),
  687.             (3, 0, 4, 7, 0),
  688.             (4, 5, 9, 8, 5),
  689.             (5, 6, 10, 9, 6),
  690.             (6, 7, 11, 10, 7),
  691.             (7, 4, 8, 11, 8),
  692.             (8, 9, 13, 12, 1),
  693.             (9, 10, 14, 13, 2),
  694.             (10, 11, 15, 14, 3),
  695.             (11, 8, 12, 15, 4)]
  696.         glDisable(GL_TEXTURE_2D)
  697.         glBegin(GL_QUADS)
  698.         for q in quads:
  699.             glNormal3fv(normals[q[4]])
  700.             glVertex3fv(verticies[q[0]])
  701.             glVertex3fv(verticies[q[1]])
  702.             glVertex3fv(verticies[q[2]])
  703.             glVertex3fv(verticies[q[3]])
  704.         
  705.         glEnd()
  706.         glEnable(GL_TEXTURE_2D)
  707.         for x in [
  708.             0,
  709.             1,
  710.             2,
  711.             3,
  712.             4,
  713.             5,
  714.             6,
  715.             7]:
  716.             for y in [
  717.                 0,
  718.                 1,
  719.                 2,
  720.                 3,
  721.                 4,
  722.                 5,
  723.                 6,
  724.                 7]:
  725.                 isBlack = (x + y % 2 + 1) % 2
  726.                 coord = chr(ord('a') + x) + chr(ord('1') + y)
  727.                 
  728.                 try:
  729.                     highlight = self.highlights[coord]
  730.                 except KeyError:
  731.                     highlight = None
  732.  
  733.                 if isBlack:
  734.                     colour = BLACK_SQUARE_COLOURS[highlight]
  735.                     self.whiteTexture.bind()
  736.                 else:
  737.                     colour = WHITE_SQUARE_COLOURS[highlight]
  738.                     self.whiteTexture.bind()
  739.                 x0 = BOARD_BORDER + x * SQUARE_WIDTH
  740.                 x1 = x0 + SQUARE_WIDTH
  741.                 z0 = BOARD_BORDER + y * SQUARE_WIDTH
  742.                 z1 = z0 + SQUARE_WIDTH
  743.                 glBegin(GL_QUADS)
  744.                 glNormal3f(0, 1, 0)
  745.                 glColor3fv(colour)
  746.                 glTexCoord2f(0, 0)
  747.                 glVertex3f(x0, 0, -z0)
  748.                 glTexCoord2f(1, 0)
  749.                 glVertex3f(x1, 0, -z0)
  750.                 glTexCoord2f(1, 1)
  751.                 glVertex3f(x1, 0, -z1)
  752.                 glTexCoord2f(0, 1)
  753.                 glVertex3f(x0, 0, -z1)
  754.                 glEnd()
  755.             
  756.         
  757.         if self.boardList is not None:
  758.             glEndList()
  759.             glCallList(self.boardList)
  760.         
  761.  
  762.     
  763.     def drawSquares(self):
  764.         '''Draw the board squares for picking'''
  765.         for u in [
  766.             0,
  767.             1,
  768.             2,
  769.             3,
  770.             4,
  771.             5,
  772.             6,
  773.             7]:
  774.             glPushName(u)
  775.             for v in [
  776.                 0,
  777.                 1,
  778.                 2,
  779.                 3,
  780.                 4,
  781.                 5,
  782.                 6,
  783.                 7]:
  784.                 glPushName(v)
  785.                 glBegin(GL_QUADS)
  786.                 x0 = BOARD_BORDER + u * SQUARE_WIDTH
  787.                 x1 = x0 + SQUARE_WIDTH
  788.                 z0 = BOARD_BORDER + v * SQUARE_WIDTH
  789.                 z1 = z0 + SQUARE_WIDTH
  790.                 glVertex3f(x0, 0, -z0)
  791.                 glVertex3f(x1, 0, -z0)
  792.                 glVertex3f(x1, 0, -z1)
  793.                 glVertex3f(x0, 0, -z1)
  794.                 glEnd()
  795.                 glPopName()
  796.             
  797.             glPopName()
  798.         
  799.  
  800.     
  801.     def drawPieces(self):
  802.         '''Draw the pieces in the scene'''
  803.         glEnable(GL_TEXTURE_2D)
  804.         for piece in self.pieces:
  805.             glPushMatrix()
  806.             glTranslatef(piece.pos[0], piece.pos[1], piece.pos[2])
  807.             piece.draw()
  808.             glPopMatrix()
  809.         
  810.         glDisable(GL_TEXTURE_2D)
  811.  
  812.     
  813.     def transformBoard(self):
  814.         '''Perform the board transform'''
  815.         glRotatef(self.boardAngle, 0, 1, 0)
  816.         glTranslatef(-OFFSET, 0, OFFSET)
  817.  
  818.  
  819.